using Microsoft.Extensions.Logging;
using SumerCoreDevOps.Infrastructure.Tcp;
using SumerCoreDevOps.Shared.Enums;
using SumerCoreDevOps.Shared.Models.Messages;

namespace SumerCoreDevOps.Infrastructure.Configuration;

/// <summary>
/// 配置变更通知服务
/// </summary>
public class ConfigurationNotificationService
{
    private readonly TcpServer _tcpServer;
    private readonly ILogger<ConfigurationNotificationService> _logger;

    public ConfigurationNotificationService(
        TcpServer tcpServer,
        ILogger<ConfigurationNotificationService> logger)
    {
        _tcpServer = tcpServer;
        _logger = logger;
    }

    /// <summary>
    /// 通知所有节点配置已变更
    /// </summary>
    public async Task NotifyConfigurationChangedAsync(
        string configKey,
        string newValue,
        string? oldValue = null,
        bool requireReconnect = false,
        string? newServerAddress = null,
        int? newTcpPort = null,
        string? description = null)
    {
        try
        {
            var connectedNodeCount = _tcpServer.GetConnectedClientsCount();
            if (connectedNodeCount == 0)
            {
                _logger.LogInformation("没有连接的节点，跳过配置变更通知");
                return;
            }

            var message = new ConfigurationChangedMessage
            {
                ConfigKey = configKey,
                NewValue = newValue,
                OldValue = oldValue,
                RequireReconnect = requireReconnect,
                NewServerAddress = newServerAddress,
                NewTcpPort = newTcpPort,
                Description = description,
                Timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds()
            };

            await _tcpServer.BroadcastMessageAsync(TcpMessageType.ConfigurationChanged, message);

            _logger.LogInformation(
                "已向 {NodeCount} 个节点发送配置变更通知: {ConfigKey} = {NewValue}, 需要重连: {RequireReconnect}",
                connectedNodeCount, configKey, newValue, requireReconnect);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "发送配置变更通知失败: {ConfigKey}", configKey);
            throw;
        }
    }

    /// <summary>
    /// 通知TCP端口变更（需要节点重新连接）
    /// </summary>
    public async Task NotifyTcpPortChangedAsync(int newPort, int oldPort, string? serverAddress = null)
    {
        await NotifyConfigurationChangedAsync(
            configKey: "TcpServerPort",
            newValue: newPort.ToString(),
            oldValue: oldPort.ToString(),
            requireReconnect: true,
            newServerAddress: serverAddress,
            newTcpPort: newPort,
            description: $"TCP服务器端口已从 {oldPort} 变更为 {newPort}，请重新连接");
    }

    /// <summary>
    /// 通知控制面板API端口变更
    /// </summary>
    public async Task NotifyControlApiPortChangedAsync(int newPort, int oldPort)
    {
        await NotifyConfigurationChangedAsync(
            configKey: "ControlApiPort",
            newValue: newPort.ToString(),
            oldValue: oldPort.ToString(),
            requireReconnect: false,
            description: $"控制面板API端口已从 {oldPort} 变更为 {newPort}");
    }
}
